package com.last.service.impl;

import com.api.city.CityApi;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.last.bean.SearchBean;
import com.last.entity.City;
import com.last.entity.PageResult;
import com.last.entity.Result;
import com.last.service.ISearchService;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SearchService implements ISearchService {

    @Autowired
    private ElasticsearchRestTemplate template;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private CityApi cityApi;

    @Override
    public PageResult<SearchBean> searchByWhere(Map<String,String> searchMap) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        String condition = searchMap.get("condition");
        if (!StringUtils.isEmpty(condition)){
            boolQuery.should(QueryBuilders.matchQuery("city", condition));
            boolQuery.should(QueryBuilders.matchQuery("area", condition));
            boolQuery.should(QueryBuilders.matchQuery("homeName", condition));
            boolQuery.should(QueryBuilders.matchQuery("homeRemark",condition));
        }


        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        // 过滤
        // 地区搜索
        if (!StringUtils.isEmpty(searchMap.get("city"))){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", searchMap.get("city"));
            boolQuery.filter(termQueryBuilder);
        }
        // 景点搜索
        if (!StringUtils.isEmpty(searchMap.get("area"))){
            boolQuery.filter(QueryBuilders.termQuery("area", searchMap.get("area")));
        }

        if (!StringUtils.isEmpty(searchMap.get("price"))){
            SortBuilder priceSortBuilder = null;
            if (searchMap.get("price").equals("1")){
                priceSortBuilder = SortBuilders.fieldSort("price").order(SortOrder.ASC);
            }else {
                priceSortBuilder = SortBuilders.fieldSort("price").order(SortOrder.DESC);
            }
            nativeSearchQueryBuilder.withSort(priceSortBuilder);
        }

        // 判断价格范围
        RangeQueryBuilder price = QueryBuilders.rangeQuery("price");
        if (!StringUtils.isEmpty(searchMap.get("minPrice"))){
            price.gte(searchMap.get("minPrice"));
            if (!StringUtils.isEmpty(searchMap.get("maxPrice"))){
                price.lt(searchMap.get("maxPrice"));
            }
            boolQuery.filter(price);
        }

        PageRequest page = null;
        // 设置分页
        if(!StringUtils.isEmpty(searchMap.get("page"))&&!StringUtils.isEmpty(searchMap.get("size"))){
            Integer pageNow = Integer.parseInt(searchMap.get("page"));
            Integer size = Integer.parseInt(searchMap.get("size"));
            page = PageRequest.of(pageNow-1,size);
            nativeSearchQueryBuilder.withPageable(page);
        }
        NativeSearchQuery build = nativeSearchQueryBuilder.withQuery(boolQuery).build();
        SearchHits<SearchBean> searchHits = template.search(build, SearchBean.class);
        List<SearchBean> searchBeans = new ArrayList<>();
        searchHits.getSearchHits().forEach(search->{
            searchBeans.add(search.getContent());
        });
        PageResult<SearchBean> pageResult = new PageResult<>();
        pageResult.setData(searchBeans);
        pageResult.setSuccess(true);
        pageResult.setTotal(searchHits.getTotalHits());
        return pageResult;
    }

    @Override
    public List<City> gainALlCity() {
        String city = stringRedisTemplate.boundValueOps("allcity").get();
        List<City> cities = new ArrayList<>();
        if (StringUtils.isEmpty(city)){
            // redis中没有
            synchronized (this){
                String secondCity = stringRedisTemplate.boundValueOps("allcity").get();
                if (StringUtils.isEmpty(secondCity)){
                    // 从数据库中获取
                    cities = cityApi.getAllCity();
                }
            }
        }else {
            try {
                cities = new ObjectMapper().readValue(city, List.class);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return cities;
    }


}
